package psn.qiuyiping.autocad.dxffile;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;

import com.cbf4file.ClassUtils;

public class DxfReactor extends DxfBlockReader {
    static final Map<String, Class<? extends DxfReactor>> REACTORFUNCS;
    static {
        REACTORFUNCS = new java.util.TreeMap<>();
        registerPackage(DxfProcessContext.class.getPackage().getName());
    }

    public static void registerPackage(String packName) {
        try {
            for (Class<?> cls : ClassUtils.getClasses(packName)) {
                ReactorName f = cls.getAnnotation(ReactorName.class);
                if (f == null) {
                    continue;
                }
                REACTORFUNCS.put(f.value(), (Class<? extends DxfReactor>) cls);
            }
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }

    public static DxfReactor getReator(String name) {
        Class<? extends DxfReactor> cls = REACTORFUNCS.get(name);
        if (cls == null) {
            System.out.println("reactor:"+name);
            cls = DxfReactor.class;
            REACTORFUNCS.put(name, cls);
        }

        try {
            return (DxfReactor) cls.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            return new DxfReactor();
        }

    }

    @Override
    public boolean readDxfBody0(DxfProcessContext context, DxfData<Object> item) {
        if (item.code == 0 || item.code == 100 ) {
            context.pop();
            context.process(item);
            return true;
        } else if (item.code == 102 ) {
            if(!"}".equals(item.getVal())){
                throw new IllegalArgumentException();
            }
            context.pop();
            return true;
        }else{
            return false;
        }
    }

    @Override
    public void readDxfBody(DxfProcessContext context, DxfData<Object> item) {
        for(Field field: this.getClass().getDeclaredFields()){
            DxfCode f = field.getAnnotation(DxfCode.class);
            if(f==null){
                return;
            }
            if(f.value()==item.code){
                try {
                    field.set(this, item.getVal());
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                return;
            }
        }
    }
}
